package dslab.mailbox;

import dslab.util.Message;
import dslab.util.WriteTask;

import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;

/**
 * mailbox specific utility class that is runnable and should run in its own thread;
 * the purpose is to process outbound write tasks in an orderly fashion and therefore
 * adhere to the single writer principle for write tasks
 */
public class WriteQueueHandler implements Runnable {
    private final String componentId;
    private final BlockingQueue<WriteTask> writeTasks;
    private final Map<String, List<Message>> mails;

    /**
     * creates a new WriteQueueHandler
     * @param componentId string representation of component
     * @param writeTasks queue where write tasks will be put to
     * @param mails reference to map with mapping of users to lists of messages
     */
    public WriteQueueHandler(String componentId, BlockingQueue<WriteTask> writeTasks, Map<String, List<Message>> mails) {
        if (writeTasks == null)
            throw new IllegalArgumentException();

        this.componentId = componentId;
        this.writeTasks = writeTasks;
        this.mails = mails;
    }

    @Override
    public void run() {
        System.out.printf("@%s: begin run%n", componentId);
        try {
            while (true) {
                // BlockingQueue is battle-tested and thread-safe
                var task = writeTasks.take();

                // execute task
                task.executeTask();

                System.out.printf("@%s: done executing task%n", componentId);
            }
        } catch (InterruptedException exception) {
            System.out.printf("@%s: stopped execution due to interruption%n", componentId);
        }
        System.out.printf("@%s: end run%n", componentId);
    }
}
